﻿#include "PlaylistManager.h"
#include<qdiriterator.h>
#include<QtConcurrent/qtconcurrentrun.h>
#include<qmediaplayer.h>
#include<qdir.h>
#include<qfileinfo.h>
#include<qmediametadata.h>
#include<taglib/fileref.h>
#include<taglib/tag.h>	
#include<taglib/mpegfile.h>
#include<taglib/flacfile.h>
#include<taglib/oggfile.h>
#include<taglib/wavfile.h>

PlaylistManager::PlaylistManager(QObject *parent)
	: QObject(parent), m_listType(ListName::Default)
	, m_adder(new QMediaPlayer(this))
{
	m_fileDirs.push_back("music");

	for (int i = 0; i < 2; i++)
	{
		m_allPlayLists.insert(static_cast<ListName>(i), new SongList);
	}
	m_listType = ListName::Default;
	m_curList = m_allPlayLists[m_listType];
}

void PlaylistManager::appendSong(const Song& s)
{
	QMutexLocker<QMutex> locker(&m_mutex);
	m_curList->appendSafe(s);
}

PlaylistManager::~PlaylistManager()
{
	QMutexLocker<QMutex> locker(&m_mutex);
	for (auto& i : m_allPlayLists)
	{
		//if (i != nullptr)
		//{
			delete i;
		//}
	}
}


void PlaylistManager::appendMusicDir(const QString& dir)
{
	QMutexLocker<QMutex> locker(&m_mutex);
	m_fileDirs.append(dir);
}

PlaylistManager& PlaylistManager::getInstance()
{
	// TODO: 在此处插入 return 语句
	static PlaylistManager manager(nullptr);
	return manager;
}

QUrl PlaylistManager::getCurUrl(int index)
{
	QMutexLocker<QMutex> locker(&m_mutex);
	if (index >= 0 && index < m_curList->size())
	{
		return (*m_curList)[index].url;
	}
	return QUrl();
}

void PlaylistManager::changeType(PlaylistManager::ListName type)
{
	m_listType = type;
	m_curList = m_allPlayLists[type];
}

SongList* PlaylistManager::getCurSongList()
{
	QMutexLocker<QMutex> locker(&m_mutex);
	return m_curList;
}

void PlaylistManager::musicFromLocal_Async(int batchSize)
{
	QMutexLocker<QMutex> locker(&m_mutex);
	auto fileDirs = m_fileDirs;
	
	QtConcurrent::run(
		[=]() {
			QStringList filter{ "*.mp3","*.flac","*.wav","*.ogg" };
			QList<Song> songList;
			static int count = 0;
			//auto dirs = m_fileDirs; // 值拷贝（需确保线程安全）

			for (auto& dir : fileDirs)
			{
				if (!QDir(dir).exists()) {
					qWarning() << "error path :" << dir;
					continue;
				}
				QDirIterator it(dir, filter, QDir::Files, QDirIterator::Subdirectories);
				while (it.hasNext()) {
					Song s;

					try {
						QString songFile = it.next();
						QFileInfo info(songFile);

						#ifdef Q_OS_WIN
						// Windows ，转换为 wchar_t* (UTF-16) 支持中文等路径
						TagLib::FileRef fileRef(songFile.toStdWString().c_str());

						#else
						// 在 Linux, macOS 等系统上，使用 UTF-8 编码的 char*
						TagLib::FileRef fileRef(songFile.toUtf8().constData());
						#endif
						TagLib::Tag* songTag = fileRef.tag();
						if (songTag != nullptr)
						{
							auto title = songTag->title();
							if (title.isEmpty())
							{
								s.songName = info.baseName();
							}
							else
							{
								s.songName = TStringToQString(title);
							}
							s.singerName = TStringToQString(songTag->artist());
						}
						else
						{
							s.songName = info.baseName();
						}

						
						s.type = this->getAudioType(&fileRef);
						auto durationPtr = fileRef.audioProperties();
						if (durationPtr != nullptr)
						{
							s.duration_s = durationPtr->lengthInSeconds();
						}
						
						s.path = info.filePath();
						s.size = info.size();
						s.url = QUrl::fromLocalFile(s.path);
					}
					catch (const std::exception& e) {
						qWarning() << "Failed to read file:" << it.filePath() << e.what();
					}
					
					songList.push_back(s);
					
					if (songList.size() >= batchSize)
					{
						m_curList->appendSafe(songList);
						emit songsScannedBatch(count);
						emit songsScannedBatch(std::move(songList));
						count = m_curList->size();
						//songList.clear();
					}
					
				}
			}
			if (!songList.empty()) {				
				m_curList->appendSafe(songList);
				qDebug() << __FUNCTION__ << "m_curList.size() = " << m_curList->size();
				emit songsScannedBatch(count);
				emit songsScannedBatch(std::move(songList));
				count = m_curList->size();
				qDebug() << "songsScannedBatch 信号被发射";
			}
			emit scanFinished();
		});
}

QString PlaylistManager::getAudioType(TagLib::FileRef* fileRef)
{
	TagLib::File* file= fileRef->file();
	if (dynamic_cast<TagLib::MPEG::File*>(file))
	{
		return "mp3";
	}
	else if (dynamic_cast<TagLib::FLAC::File*>(file))
	{
		return "flac";
	}
	else if(dynamic_cast<TagLib::Ogg::File*>(file))
	{
		return "ogg";
	}
	else if(dynamic_cast<TagLib::RIFF::WAV::File*>(file))
	{
		return "wav";
	}

	return "unknown";
}

void PlaylistManager::addSongMessage_Async()
{
	QMutexLocker<QMutex> locker(&m_mutex);
	//connect(this, &PlaylistManager::scanFinished, [this]() {
	//	for (auto& song : m_songList.getLocalList())
	//	{
	//		m_adder->setSource(QUrl::fromLocalFile(song.path));
	//		QMediaMetaData data = m_adder->metaData();
	//		song.duration_s = data.value(data.Duration).toInt();			
	//	}
	//});	

}


